
/** Matrix.h
 * File contains class with all matrix relevant operations.
 * It overloads some operators and has basic functions
 * such as inverting. */

#include <cstdlib>

#define FREENULL(a) do { free(a); a = nullptr; } while(0);

/* Matrix is the class containing all matrix operations and some features
 * to provide efficient and simple working with matrices in your code. */
class Matrix {
public:
	/* Constructors/Destructor */
	/* creates the matrix with 1x1 dimension */
	Matrix();
	/* creates a param1 square matrix */
	Matrix(int i_dim);
	/* creates a param1 x param2 matrix */
	Matrix(int i_row, int i_col);
	/* creates a matrix with param1 as content.
	 * if param4 is set, it frees the given pointer afterwards. */
	Matrix(double **ppd_matrix, int i_row, int i_col, bool free = false);
	/* free memory, set pointers to nullptr */
	~Matrix();

public:
	/* Operator Overloads */
	Matrix operator+(const Matrix &other);
	Matrix operator+(double &value);

	Matrix operator-(const Matrix &other);
	Matrix operator-(double &value);

	Matrix operator*(const Matrix &other);
	Matrix operator*(double &value);

	Matrix operator/(const Matrix &other);
	Matrix operator/(double &value);

	Matrix operator=(const Matrix &other);
	Matrix operator==(const Matrix &other);
	Matrix operator!=(const Matrix &other);

public: 
	/* Mathematical methods */
	/* power every element with param1 */
	void pow(float f_power);
	/* root every element by the param1'th root
	 * actually just calls pow with 1/param1 */
	void root(float f_root);
	/* mathematically inverse the matrix */
	void inverse();

public:
	/* dimension related methods (possible data loss) */
	void appendMatrix(Matrix mat, int i_pos); /* add a matrix with the same amount of rows
											   * before columns param2 */
	 
public: // Getter/Setter
	inline int getRowCount();
	inline int getColumnCount();
	inline void setMatrixValue(double d_value, int i_row, int i_col);
	inline double getMatrixValue(int i_row, int i_col);
	double **getMatrix(); /* create a copy of the matrix and return a pointer to it */
	/* get a pointer to a copy of rows param1 to param2 and columns param3 to param4 */
	double **getMatrix(int i_row1, int i_row2, int i_col1, int i_col2);
	inline long getSize(); /* size of matrix in byte */
private: // Attributes
	int i_row;
	int i_column;
	double **ppd_matrix; // row is first dimension, column is second
};